package com.mt.common.system.service.impl;

import com.mt.common.core.exception.BusinessException;
import com.mt.common.core.utils.EntityMapUtils;
import com.mt.common.core.web.BaseService;
import com.mt.common.core.web.base.PageDTO;
import com.mt.common.core.web.base.PageResultDTO;
import com.mt.common.system.entity.ScheduledTask;
import com.mt.common.system.mapper.ScheduledTaskDao;
import com.mt.common.system.service.QuartzJobService;
import com.mt.common.system.service.ScheduledTaskService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
@Transactional
public class ScheduledTaskServiceBean extends BaseService implements ScheduledTaskService {

    private static Logger logger = LogManager.getLogger();

	@Autowired
	private ScheduledTaskDao scheduledTaskDao;

	@Resource
	private RedisTemplate<String, List<ScheduledTask>> redisTemplate;

	@Autowired
	StringRedisTemplate stringRedisTemplate;

	@Autowired
	private QuartzJobService quartzJobService;

	@Autowired
	private Scheduler scheduler;

	/**
	 * 根据分页参数查询定时任务集合
	 *
	 * @param pageDTO 分页条件
	 */
	@Override
	public PageResultDTO findScheduledTasks(PageDTO pageDTO){
        pageDTO.setStartIndex((pageDTO.getCurrentPage()-1)*pageDTO.getPageSize());
		//TODO:请在此校验参数的合法性
		this.validateFindScheduledTasks(pageDTO);
		//List<ScheduledTask> scheduledTaskDTOS = this.scheduledTaskDao.findScheduledTasks(pageDTO);
		//Long totalCount = this.scheduledTaskDao.findScheduledTaskTotalCount(pageDTO);

		PageResultDTO pageResultDTO = new PageResultDTO();
		List<ScheduledTask> all = quartzJobService.findAll();
		pageResultDTO.setTotalCount((long) all.size());
		pageResultDTO.setDatas(all);
		return pageResultDTO;
	}

	/**
	 * 查询全部定时任务集合
	 *
	 */
	@Override
	public List<ScheduledTask> findAllScheduledTasks(){
		return this.scheduledTaskDao.findAllScheduledTasks();
	}

	/**
	 * 查询所有定时任务集合(只提取ID 和 Name)
	 *
	 */
	@Override
	public List<ScheduledTask> findAllScheduledTasksWithIdName(){
		//TODO:请在此校验参数的合法性
		this.validateFindAllScheduledTasksWithIdName();
		return this.scheduledTaskDao.findAllScheduledTasksWithIdName();
	}

	/**
	 * 根据名称查询定时任务集合(只提取ID 和 Name)
	 *
	 * @param scheduledTaskName 名称
	 */
	@Override
	public List<ScheduledTask> findScheduledTasksWithIdNameByName(String scheduledTaskName){
		//TODO:请在此校验参数的合法性
		this.validateFindScheduledTasksWithIdNameByName(scheduledTaskName);
		//TODO:缓存取对应参数
		Set<String> keys = stringRedisTemplate.keys("searchData:ScheduledTask_where_scheduledTaskName_" + scheduledTaskName);
		List<ScheduledTask> scheduledTasks = new ArrayList<>();
		if (keys.isEmpty()) {
		scheduledTasks = this.scheduledTaskDao.findScheduledTasksWithIdNameByName(scheduledTaskName);
		redisTemplate.opsForValue().set("searchData:ScheduledTask_where_scheduledTaskName_" + scheduledTaskName, scheduledTasks, 30, TimeUnit.DAYS);
		} else {
		scheduledTasks = redisTemplate.opsForValue().get("searchData:ScheduledTask_where_scheduledTaskName_" + scheduledTaskName);
		}
		return scheduledTasks;
	}

	/**
	 * 根据ID查询指定的定时任务(只提取ID 和 Name)
	 *
	 * @param scheduledTaskId Id
	 */
	@Override
	public ScheduledTask findScheduledTasksWithIdNameById(Long scheduledTaskId){
		//TODO:请在此校验参数的合法性
		this.validateFindScheduledTasksWithIdNameById(scheduledTaskId);
		return this.scheduledTaskDao.findScheduledTasksWithIdNameById(scheduledTaskId);
	}

	/**
	 * 根据ID查询指定的定时任务
	 *
	 * @param scheduledTaskId Id
	 */
	@Override
	public ScheduledTask findScheduledTask(Long scheduledTaskId){
		//TODO:请在此校验参数的合法性
		this.validateFindScheduledTask(scheduledTaskId);
		return this.scheduledTaskDao.findScheduledTask(scheduledTaskId);
	}

	/**
	 * 根据ID查询指定的定时任务(包含外键)
	 *
	 * @param scheduledTaskId Id
	 */
	@Override
	public ScheduledTask findScheduledTaskWithForeignName(Long scheduledTaskId){
		//TODO:请在此校验参数的合法性
		this.validateFindScheduledTaskWithForeignName(scheduledTaskId);
		return this.scheduledTaskDao.findScheduledTaskWithForeignName(scheduledTaskId);
	}

	/**
	 * 新增定时任务
	 *
	 * @param scheduledTask 实体对象
	 */
	@Override
	public ScheduledTask saveScheduledTask(ScheduledTask scheduledTask) throws SchedulerException {
		//TODO:请在此校验参数的合法性
		//加入定时器
		Map<String, Object> map = EntityMapUtils.entityToMap(scheduledTask);
		quartzJobService.addJob(null,scheduledTask.getJobName(),scheduledTask.getJobGroup(),scheduledTask.getCron(),map);
		return scheduledTask;
	}

	/**
	 * 更新定时任务
	 *
	 * @param scheduledTask 实体对象
	 */
	@Override
	public ScheduledTask updateScheduledTask(ScheduledTask scheduledTask){
		//TODO:请在此校验参数的合法性
		Map<String, Object> map = EntityMapUtils.entityToMap(scheduledTask);
		this.quartzJobService.updateJob(scheduledTask.getJobName(),scheduledTask.getJobGroup(),scheduledTask.getCron(),map);
		return scheduledTask;
	}

	/**
	 * 根据ID删除定时任务
	 *
	 * @param
	 */
	@Override
	public void deleteScheduledTask(String jobName,String groupName){
		quartzJobService.deleteJob(jobName,groupName);

	}

	@Override
	public void pauseJob(String jobName, String groupName) {
		this.quartzJobService.pauseJob(jobName,groupName);
	}

	@Override
	public void resumeJob(String jobName, String groupName) {
		this.quartzJobService.resumeJob(jobName,groupName);
	}

	@Override
	public void pauseAllJobs() {
		this.quartzJobService.pauseAllJobs();
	}

	@Override
	public void resumeAllJobs() {
		this.quartzJobService.resumeAllJobs();
	}
	//TODO:---------------验证-------------------

	private void validateFindScheduledTasks(PageDTO pageDTO) {
	//TODO:请使用下面方法添加数据过滤条件
	//		pageDTO.addFilter("creatorId",this.getLoginUserId());
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateScheduledTask()写法
	}

	private void validateFindScheduledTasksWithIdNameByName(String scheduledTaskName) {
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateScheduledTask()写法
	}


	private void validateFindAllScheduledTasksWithIdName() {
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateScheduledTask()写法
	}

	private void validateFindScheduledTasksWithIdNameById(Long scheduledTaskId) {
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateScheduledTask()写法
	}

	private void validateFindScheduledTask(Long scheduledTaskId) {
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateScheduledTask()写法
	}

	private void validateFindScheduledTaskWithForeignName(Long scheduledTaskId) {
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateScheduledTask()写法
	}

	private void validateSaveScheduledTask(ScheduledTask scheduledTask) {
	//不为空判断
	if (scheduledTask.getEid() != null || scheduledTask.getCreatorId() != null || scheduledTask.getCreateDatetime() != null) {
	throw new BusinessException("非法请求");
	}
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateScheduledTask()写法
	}

	private void validateUpdateScheduledTask(ScheduledTask scheduledTask) {
	//不为空判断
	if (scheduledTask.getEid() == null) {
	throw new BusinessException("唯一标识不能为空");
	}
	//是否存在判断
	if (this.scheduledTaskDao.findScheduledTaskTotalCount(PageDTO.create(ScheduledTask.FIELD_ID, scheduledTask.getEid())) == 0) {
	throw new BusinessException("修改的定时任务 " + scheduledTask.getName() + " 不存在，修改失败，请重试或联系管理员");
	}
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateScheduledTask()写法
	}

	private void validateDeleteScheduledTask(Long scheduledTaskId) {
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateScheduledTask()写法
	}

	@Override
	public boolean canDownloadAttachment(String formName, Long id) {
	return true;
	}

}
